home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-08  |  19.1 KB  |  846 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                                                                            */
  4. /*        ------------         Bit-Bucket Software <no-Inc>                    */
  5. /*        \ 10001101 /         Writers and Distributors of                    */
  6. /*         \ 011110 /          No-Cost<no-tm> Software.                        */
  7. /*          \ 1011 /                                                            */
  8. /*           ------                                                            */
  9. /*                                                                            */
  10. /*    Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello    */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                  This module was written by Vince Perriello                */
  14. /*                       with code from several authors                        */
  15. /*                                                                            */
  16. /*                                                                            */
  17. /*                  Miscellaneous routines used by BinkleyTerm                */
  18. /*                                                                            */
  19. /*                                                                            */
  20. /*      For complete    details  of the licensing restrictions, please refer    */
  21. /*      to the License  agreement,  which  is published in its entirety in    */
  22. /*      the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  23. /*                                                                            */
  24. /*      USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  25. /*      BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  26. /*      THIS    AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,    OR IF YOU DO    */
  27. /*      NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  28. /*      AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  29. /*      USE    THIS  FILE    WITHOUT  HAVING   ACCEPTED    THE  TERMS    OF     THE    */
  30. /*      BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER    AGREEMENT AS YOU    */
  31. /*      ARE ABLE TO REACH WITH THE AUTHORS.                                    */
  32. /*                                                                            */
  33. /*                                                                            */
  34. /*      The Authors can be reached at the following addresses:                */
  35. /*                                                                            */
  36. /*      Robert C. Hartman                      Vincent E. Perriello            */
  37. /*      Spark Software                         VEP Software                    */
  38. /*      427-3 Amherst Street                     111 Carroll Street             */
  39. /*      CS2032, Suite 232                      Naugatuck, CT 06770            */
  40. /*      Nashua, NH 03061                                                        */
  41. /*                                                                            */
  42. /*      FidoNet 1:132/101                      FidoNet 1:141/491                */
  43. /*      Data      (603) 888-8179                 Data     (203) 729-7569         */
  44. /*                                                                            */
  45. /*      Please feel free to contact us at any time to share your comments     */
  46. /*      about our software and/or licensing policies.                         */
  47. /*                                                                            */
  48. /*--------------------------------------------------------------------------*/
  49.  
  50. #include <dos.h>
  51. #include <time.h>
  52. #include <ctype.h>
  53. #include <stdio.h>
  54. #include <stdarg.h>
  55. #include <string.h>
  56. #include <stdlib.h>
  57. #include <conio.h>
  58. #include <process.h>
  59. #include <io.h>       /*PLF Fri  05-05-1989  08:54:00 */
  60. #include <stdlib.h>   /*PLF Mon  05-08-1989  05:58:03 */
  61.  
  62. #ifdef __TURBOC__
  63. #include <mem.h>
  64. #else
  65. #include <memory.h>
  66. #endif
  67.  
  68. #include "com.h"
  69. #include "xfer.h"
  70. #include "zmodem.h"
  71. #include "keybd.h"
  72. #include "sbuf.h"
  73. #include "sched.h"
  74. #include "externs.h"
  75. #include "prototyp.h"
  76. #ifdef OS_2  /*PLF Fri    05-05-1989    07:24:36 */
  77. #define INCL_DOSFILEMGR
  78. #define INCL_DOSPROCESS
  79. #define INCL_VIO
  80. #include <os2.h>
  81. #endif
  82.  
  83. static char newstring[100];
  84. static void fill_in_status (void);
  85.  
  86.  
  87. int dexists (filename)
  88. char *filename;
  89. {
  90.    return(!access(filename, 0)); /*PLF Fri    05-05-1989    08:05:17 */
  91. }
  92.  
  93. /*PLF Sat  05-06-1989  00:00:01
  94.  * dfind() used to be here. It was replaced with the stuff in find.c
  95.  *
  96.  */
  97.  
  98.  
  99. int set_baud (baudrate, log)
  100. unsigned baudrate;
  101. int log;
  102. {
  103.    register int i;
  104.  
  105.    if (!baudrate)                                 /* "FAST" might do this      */
  106.       return (0);
  107.  
  108.    /* For 1200/75 split speed modems */
  109.    if ((baudrate == 1275) || (baudrate == 7512))
  110.       baudrate = 1200;
  111.  
  112.    if (max_baud && (baudrate > max_baud))
  113.       baudrate = max_baud;
  114.    else if (lock_baud)
  115.       baudrate = max_baud;
  116.  
  117.    for (i = 0; btypes[i].str != NULL; i++)
  118.       {
  119.       if (atoi (btypes[i].str) == baudrate)
  120.          {
  121.          if (baud != i)                          /* same as what we have?      */
  122.             {
  123.             if (log && !un_attended)
  124.                status_line ("#Setting baud to %u", baudrate);
  125.             baud = i;                             /* need this for ALT-B       */
  126.             cur_baud = baudrate;            /*PLF Sat  05-06-1989  04:38:54 */
  127.             MDM_ENABLE (btypes[baud].rate);
  128.             }
  129.          if (un_attended && fullscreen)
  130.             {
  131.             sb_move (settingswin, SET_PORT_ROW, SET_COL);
  132.             sprintf (junk, "%-5u Com%d", baudrate, port_ptr + 1);
  133.             sb_puts (settingswin, junk);
  134.             sb_show ();
  135.             }
  136.          return (1);
  137.          }
  138.       }
  139.    return (0);
  140. }
  141.  
  142. static char *specifiers = "!*+:# ";
  143. static struct tm *tp;
  144. static time_t ltime;
  145. static char jbuf[20];
  146.  
  147. void status_line (char *fmt,...)
  148. {
  149.    va_list arg_ptr;
  150.    /*PLF extern int errno; include stdlib.h instead. This fails in large/compact model */
  151.  
  152.    va_start (arg_ptr, fmt);
  153.    errno = 0;
  154.    vsprintf (e_input, fmt, arg_ptr);
  155.    time (<ime);
  156.    tp = localtime (<ime);
  157.    if ((!fullscreen) || (!un_attended))
  158.       {
  159.       cprintf ("\r\n%c %02i %03s %02i:%02i:%02i BINK %s", e_input[0],
  160.           tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
  161.                &e_input[1]);
  162.       }
  163.    else
  164.       {
  165.       sprintf (stat_line, "%c %02i:%02i:%02i %-64.64s", e_input[0],
  166.                tp->tm_hour, tp->tm_min, tp->tm_sec, &e_input[1]);
  167.       fill_in_status ();
  168.       }
  169.    if ((status_log != NULL) &&
  170.        ((strchr (specifiers, e_input[0]) - strchr (specifiers, '!')) <= loglevel))
  171.       {
  172.       fprintf (status_log, "%c %02i %03s %02i:%02i:%02i BINK %s\n", e_input[0],
  173.           tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
  174.                &e_input[1]);
  175.       fflush (status_log);
  176.       real_flush (fileno (status_log));
  177.       }
  178.  
  179.    va_end (arg_ptr);
  180. }
  181.  
  182. /*--------------------------------------------------------------------------*/
  183. /* THROUGHPUT                                                                */
  184. /* Print throughput message at end of transfer                                */
  185. /*--------------------------------------------------------------------------*/
  186. void throughput (opt, bytes)
  187. int opt;
  188. unsigned long bytes;
  189.  
  190. {
  191.    static byte *scrn = "+CPS: %lu (%lu bytes)  Efficiency: %lu%%";
  192.    static unsigned long started = 0L;
  193.    static unsigned long elapsed;
  194.    static unsigned long cps;
  195.  
  196.    if (!opt)
  197.       started = time (NULL);
  198.    else if (started)
  199.       {
  200.       elapsed = time (NULL) - started;
  201.       if (elapsed == 0L)
  202.          return;
  203.       cps = bytes / elapsed;
  204.       started = (cps * 1000L) / ((long) cur_baud);
  205.       status_line (scrn, cps, bytes, started);
  206.       }
  207. }                                                 /* throughput */
  208.  
  209. static void fill_in_status ()
  210. {
  211.  
  212.    time (<ime);
  213.    tp = localtime (<ime);
  214.    if (fullscreen)
  215.       {
  216.       sb_scrl (callwin, 1);
  217.       sb_move (callwin, CALL_STAT_ROW, 2);
  218.       sb_puts (callwin, stat_line);
  219.       sb_move (settingswin, SET_TIME_ROW, SET_TIME_COL);
  220.       sprintf (junk, "%s %s %02d @ %02d:%02d",
  221.                wkday[tp->tm_wday], mtext[tp->tm_mon], tp->tm_mday,
  222.                tp->tm_hour, tp->tm_min);
  223.       sb_puts (settingswin, junk);
  224.       sb_show ();
  225.       }
  226. }
  227.  
  228. void clear_statusline ()
  229. {
  230.    if (fullscreen)
  231.       sb_fillc (callwin, ' ');
  232. }
  233.  
  234. int got_error (string1, string2)
  235. char *string1, *string2;
  236. {
  237.    /* extern int errno; */
  238.  
  239. #ifdef __TURBOC__
  240. /*      Since TurboC doesn't handle errno correctly, zero it and ignore. */
  241.       errno = 0;
  242. #else
  243.    if (errno == 0x18)
  244.       errno = 0;
  245.    if (errno != 0)
  246.       {
  247.       status_line ("!Error %d, Can't %s %s", errno, string1, string2);
  248.       errno = 0;
  249.       return (1);
  250.       }
  251. #endif
  252.    return (0);
  253. }
  254.  
  255. void set_xy (string)
  256. char *string;
  257. {
  258.    WRITE_ANSI ('\r');
  259.    WRITE_ANSI ('\n');
  260.    scr_printf (string);
  261.    locate_x = wherex ();
  262.    locate_y = wherey ();
  263. }
  264.  
  265. void message (string)
  266. char *string;
  267. {
  268.    if (string != NULL)
  269.       {
  270.       status_line (" %s", string);
  271.       }
  272. }
  273.  
  274. void time_release ()
  275. {
  276. #ifndef OS_2  /*PLF Fri  05-05-1989  07:06:27 */
  277.    dos_break_off ();                            /* Turn off ^C trapping */
  278.  
  279.    if (have_dv)
  280.       {
  281.       dv_pause ();
  282.       }
  283.    else if (have_ddos)
  284.       {
  285.       ddos_pause ();
  286.       }
  287.    else if (have_tv)
  288.       {
  289.       tv_pause ();
  290.       }
  291.    else if (have_ml)
  292.       {
  293.       ml_pause ();
  294.       }
  295. #else /*PLF Fri  05-05-1989  07:06:44 */
  296.  
  297. /* OS/2 notes. I take it this function will be called when we want to
  298.  * give up the rest of the current time slice. I have interpreted this to
  299.  * be DosSleep(1L) for Binkley Term in os/2. Perhaps you may think it
  300.  * should be DosSleep(0L). I include the following to help you decide:
  301. */
  302.  
  303.     /*
  304.      * The DosSleep function causes the current thread to wait for a
  305.      * specified interval of time or, if the requested interval is zero, to
  306.      * give up the remainder of the current time slice. The actual time the
  307.      * thread waits can be off by a clock tick or two, depending on the
  308.      * execution status of the other threads running in the system. If the
  309.      * specified time interval is zero, the process will forego the
  310.      * remainder of its CPU time slice but will be scheduled normally for
  311.      * its next time slice. Otherwise, the time is given in milliseconds,
  312.      * rounded up to the resolution of the scheduler clock.
  313.      *
  314.      * The DosSleep function is a family API function.
  315.      *
  316.      * Comments
  317.      *
  318.      * For short time intervals, the rounding-up process combined with the
  319.      * thread-priority interactions can cause the waiting interval to be
  320.      * longer than the requested time. Also, when a process continues after
  321.      * suspension, it is scheduled for execution, although that execution
  322.      * could be delayed by hardware interrupts or by another thread running
  323.      * at a higher priority. In no case should the DosSleep function be
  324.      * substituted for a real-time clock because the rounding of the sleep
  325.      * interval will cause accumulative errors.
  326.      */
  327.  
  328.     DosSleep(1L);
  329.  
  330. #endif /*PLF Fri  05-05-1989  07:06:52 */
  331. }
  332.  
  333. void adios (n)
  334. int n;
  335. {
  336.    if (vfossil_installed)
  337.       vfossil_close ();
  338.  
  339.    MDM_DISABLE ();
  340.    exit (n);
  341. }
  342.  
  343. char *fancy_str (string)
  344. char *string;
  345. {
  346.    register int flag = 0;
  347.    char *s;
  348.  
  349.    s = string;
  350.  
  351.    while (*string)
  352.       {
  353.       if (isalpha (*string))                     /* If alphabetic,       */
  354.          {
  355.          if (flag)                                 /* already saw one?   */
  356.             *string = tolower (*string);         /* Yes, lowercase it  */
  357.          else
  358.             {
  359.             flag = 1;                             /* first one, flag it */
  360.             *string = toupper (*string);         /* Uppercase it       */
  361.             }
  362.          }
  363.       else /* if not alphabetic  */ flag = 0;     /* reset alpha flag   */
  364.       string++;
  365.       }
  366.  
  367.    return (s);
  368. }
  369.  
  370. void timer (interval)
  371. int interval;
  372. {
  373.    long timeout, timerset ();
  374.  
  375.    timeout = timerset (interval * 10);
  376.    while (!timeup (timeout))
  377.       time_release ();
  378. }
  379.  
  380. void big_pause (secs)
  381. int secs;
  382. {
  383.    long timeout, timerset ();
  384.  
  385.    timeout = timerset (secs * 100);
  386.    while (!timeup (timeout))
  387.       {
  388.       if (CHAR_AVAIL ())
  389.      break;
  390.       time_release ();
  391.       }
  392. }
  393.  
  394. unsigned int com_getc (t)
  395. int t;
  396. {
  397.    unsigned char c;
  398.    long t1;
  399.    extern long timerset ();
  400.  
  401.    if (CHAR_AVAIL ())
  402.       {
  403.       c = (char) (MODEM_IN () & 0xff);
  404.       }
  405.    else
  406.       {
  407.       t1 = timerset (t * 100);
  408.       while (!CHAR_AVAIL ())
  409.          {
  410.          if (timeup (t1))
  411.             {
  412.             return (EOF);
  413.             }
  414.  
  415.          /*
  416.           * This should work because we only do TIMED_READ when we have
  417.           * carrier
  418.           */
  419.          if (!CARRIER)
  420.             {
  421.             return (EOF);
  422.             }
  423.          time_release ();
  424.          }
  425.       c = (char) (MODEM_IN () & 0xff);
  426.       }
  427.    return (c);
  428. }
  429.  
  430. /* Z F R E E -- Return total number of free bytes on drive specified */
  431. #ifndef OS_2 /*PLF Fri    05-05-1989    07:14:36 */
  432. long zfree (drive)
  433. char *drive;
  434. {
  435.    union REGS r;
  436.  
  437.    unsigned char driveno;
  438.    long stat;
  439.  
  440.    if (drive[0] != '\0' && drive[1] == ':')
  441.       {
  442.       driveno = islower (*drive) ? toupper (*drive) : *drive;
  443.       driveno = driveno - 'A' + 1;
  444.       }
  445.    else driveno = 0;                             /* Default drive     */
  446.  
  447.    r.x.ax = 0x3600;                              /* get free space     */
  448.    r.h.dl = driveno;                             /* on this drive     */
  449.    int86 (0x21, &r, &r);                         /* go do it         */
  450.  
  451.    if (r.x.ax == 0xffff)                         /* error return??     */
  452.       return (0);
  453.  
  454.    stat = (long) r.x.bx                          /* bx = clusters avail  */
  455.       * (long) r.x.ax                             /* ax = sectors/clust     */
  456.       * (long) r.x.cx;                             /* cx = bytes/sector     */
  457.  
  458.    return (stat);
  459. }
  460. #else  /*PLF Fri  05-05-1989  07:14:36 */
  461. long zfree(char *path)
  462. {
  463.     int drive;
  464.     FSALLOCATE dt;
  465.  
  466.     if(!path || !*path)
  467.         drive = 0;
  468.     else
  469.         drive = tolower(*path) - 'a' + 1;
  470.     DosQFSInfo(drive,1, (char far *) &dt, sizeof(FSALLOCATE));
  471.     return( dt.cSectorUnit *
  472.             dt.cUnitAvail *
  473.             dt.cbSector );
  474. }
  475. #endif /*PLF Fri  05-05-1989  07:14:36 */
  476.  
  477. void scr_printf (string)
  478. char *string;
  479. {
  480.    if (string != NULL)
  481. #ifdef OS_2  /*PLF Fri    05-05-1989    07:17:59 */
  482.     /* This may have to be either VioWrtTTY() or VioWrtTTy()
  483.      *    depending on which version of the
  484.      *    bse*.h files you have for os/2
  485.      */
  486.     (void) VioWrtTTY(string, (USHORT) strlen(string), (HVIO) 0L);
  487. #else
  488.       while (*string != 0)
  489.          WRITE_ANSI (*string++);
  490. #endif
  491. }
  492.  
  493. void send_can ()
  494. {
  495.    int i;
  496. #ifdef OS_2 /*PLF Sat  05-06-1989  09:11:09 */
  497.     CLEAR_OUTBOUND();
  498.     CLEAR_INBOUND();
  499. #endif
  500.  
  501.    for (i = 0; i < 10; i++)
  502.       SENDBYTE (CAN);
  503.    for (i = 0; i < 10; i++)
  504.       SENDBYTE (BS);
  505. }
  506.  
  507. void invent_pkt_name (string)
  508. char string[];
  509.  
  510. {
  511.    struct tm *tp;
  512.    time_t ltime;
  513.  
  514.    time (<ime);
  515.    tp = localtime (<ime);
  516.    sprintf (string, "%02i%02i%02i%02i.pkt",
  517.             tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
  518. }
  519.  
  520. static char *suffixes[8] = {
  521.                             "SU", "MO", "TU", "WE", "TH", "FR", "SA", NULL
  522. };
  523.  
  524. int is_arcmail (p, n)
  525. char *p;
  526. int n;
  527. {
  528.    int i;
  529.    char c[128];
  530.  
  531.    if (!isdigit (p[n]))
  532.       {
  533.       return (0);
  534.       }
  535.  
  536.    strcpy (c, p);
  537.    strupr (c);
  538.  
  539.    for (i = n - 11; i < n - 3; i++)
  540.       {
  541.       if ((!isdigit (c[i])) && ((c[i] > 'F') || (c[i] < 'A')))
  542.          return (0);
  543.       }
  544.  
  545.    for (i = 0; i < 7; i++)
  546.       {
  547.       if (strnicmp (&c[n - 2], suffixes[i], 2) == 0)
  548.          break;
  549.       }
  550.  
  551.    if (i >= 7)
  552.       {
  553.       return (0);
  554.       }
  555.  
  556.    got_arcmail = 1;
  557.    return (1);
  558. }
  559.  
  560. int get_number (target)
  561. char *target;
  562. {
  563.    int zone, net, node, point;
  564.    int k;
  565.  
  566.    fgets (target, 100, stdin);
  567.    k = strlen (target);
  568.    if (k == 1)
  569.       return (0);
  570.    target[--k] = '\0';                           /* no '\n' */
  571.    if (!isdigit (target[0]) && target[0] != '\"')
  572.       {
  573.       fidouser (target, &zone, &net, &node, &point);
  574.       if ((net != -1) && (node != -1) && (zone != -1))
  575.          {
  576.          if (zone == alias[0].Zone)
  577.             sprintf (target, "%d/%d", net, node);
  578.          else sprintf (target, "%d:%d/%d", zone, net, node);
  579.          }
  580.       else return (0);                             /* Gotta have addr */
  581.       }
  582.    return (1);
  583. }
  584.  
  585. void gong ()
  586. {
  587.    long t, timerset ();
  588.    int i;
  589.  
  590.    if (!gong_allowed)
  591.       return;
  592.  
  593.    for (i = 0; i < 15; i++)
  594.       {
  595.       WRITE_ANSI ('\07');                        /* Bell code       */
  596.       t = timerset (100);                         /* 1 second        */
  597.       while (!timeup (t))
  598.          {
  599.          if (KEYPRESS ())                         /* If key pressed, */
  600.             {
  601.             READKB ();                             /* Throw it away    */
  602.             return;                              /* And get out     */
  603.             }
  604.          }
  605.       }
  606. }
  607.  
  608. char *skip_blanks (string)
  609. char *string;
  610. {
  611.    while (*string && isspace (*string))
  612.       ++string;
  613.    return (string);
  614. }
  615.  
  616. char *skip_to_blank (string)
  617. char *string;
  618. {
  619.    while (*string && (!isspace (*string)))
  620.       ++string;
  621.    return (string);
  622. }
  623.  
  624. #ifdef DEBUG
  625. void show_debug_name (string)
  626. char *string;
  627. {
  628.    int x, y;
  629.    static char *filler = "                           ";
  630.  
  631.    x = wherex ();
  632.    y = wherey ();
  633.    gotoxy (40, 0);
  634.    scr_printf (string);
  635.    scr_printf (&filler[strlen (string)]);
  636.    gotoxy (x, y);
  637. }
  638. #endif
  639.  
  640. int parse (input, list)
  641. char *input;
  642. struct parse_list list[];
  643.  
  644. {
  645.    int i;
  646.  
  647.    for (i = 0; list[i].p_length; i++)
  648.       {
  649.       if (strnicmp (input, list[i].p_string, list[i].p_length) == 0)
  650.          return (++i);
  651.       }
  652.    return (-1);
  653. }
  654.  
  655. void change_prompt ()
  656. {
  657.    char *s;
  658.  
  659.    if (newstring[0])
  660.       {
  661.       putenv (newstring);
  662.       return;
  663.       }
  664.  
  665.    strcpy (newstring, "PROMPT=[");
  666.    strcat (newstring, xfer_id);
  667. #ifdef OVERLAYS
  668.    strcat (newstring, "-Overlay");
  669. #endif
  670.    strcat (newstring, " Shell]$_");
  671.    s = getenv ("PROMPT");
  672.    if (s)
  673.       {
  674.       strcat (newstring, s);
  675.       }
  676.    else
  677.       {
  678.       strcat (newstring, "$P$G");
  679.       }
  680.  
  681.    putenv (newstring);
  682. }
  683.  
  684. void update_files (t)
  685. int t;
  686. {
  687.    char s[10];
  688.  
  689.    if (un_attended && fullscreen)
  690.       {
  691.       if (t)
  692.          {
  693.          ++hist.files_out;
  694.          }
  695.       else
  696.          {
  697.          ++hist.files_in;
  698.          }
  699.  
  700.       sb_move (historywin, HIST_FILE_ROW, HIST_COL);
  701.       sprintf (s, "%d/%d", hist.files_in, hist.files_out);
  702.       sb_puts (historywin, s);
  703.       sb_show ();
  704.       }
  705. }
  706.  
  707. static char *last_str[] = {
  708.                            "     None    ",
  709.                            "     WaZOO   ",
  710.                            "     FSC-0001",
  711.                            "     BBS     ",
  712.                            "     Ext Mail"
  713. };
  714.  
  715. void last_type (n, zone, net, node)
  716. int n;
  717. int zone;
  718. int net;
  719. int node;
  720. {
  721.    int i;
  722.    char j[20];
  723.  
  724.    if (fullscreen)
  725.       sb_move (historywin, HIST_LAST_ROW, HIST_COL2);
  726.  
  727.    if ((n == 1) || (n == 2))
  728.       {
  729.       if ((zone != -1000) && (net > 0))
  730.          {
  731.          sprintf (j, "%d:%d/%d", zone, net, node);
  732.          for (i = strlen (j); i < 13; i++)
  733.             j[i] = ' ';
  734.          j[i] = '\0';
  735.          hist.last_zone = zone;
  736.          hist.last_net = net;
  737.          hist.last_node = node;
  738.          }
  739.       else
  740.          {
  741.          strcpy (j, "     FSC-0001");
  742.          }
  743.       if (fullscreen)
  744.          sb_puts (historywin, j);
  745.       }
  746.    else
  747.       {
  748.       if ((n < 0) || (n > 4))
  749.          n = 0;
  750.  
  751.       if (fullscreen)
  752.          sb_puts (historywin, last_str[n]);
  753.       }
  754.  
  755.    hist.last_caller = n;
  756. }
  757.  
  758.  
  759. /*--------------------------------------------------------------------------*/
  760. /* CHECK_NETFILE -- find out if the file we've got is a netfile.            */
  761. /*--------------------------------------------------------------------------*/
  762.  
  763. char *check_netfile (fname)
  764. char *fname;
  765. {
  766.    register byte *p;
  767.    register int n;
  768.  
  769.    p = fname;
  770.    n = strlen (p) - 1;
  771.  
  772.    if ((p[n] == 't') && (p[n - 1] == 'k') && (p[n - 2] == 'p') && (p[n - 3] == '.'))
  773.       {
  774.       got_packet = 1;
  775.       got_mail = 1;
  776.       p = "Mail Packet ";
  777.       }
  778.    else if (is_arcmail (p, n))
  779.       {
  780.       got_mail = 1;
  781.       p = "Compressed Mail ";
  782.       }
  783.    else
  784.       {
  785.       /* Don't set 'got_mail' if it's a .REQ file */
  786.       if ((p[n] != 'q') || (p[n - 1] != 'e') || (p[n - 2] != 'r') || (p[n - 3] != '.'))
  787.          got_mail = 1;
  788.       p = "Net File ";
  789.       }
  790.  
  791.    return (p);
  792. }
  793.  
  794. /*--------------------------------------------------------------------------*/
  795. /* UNIQUE_NAME                                                                */
  796. /* Increments the suffix of a filename as necessary to make the name unique */
  797. /*--------------------------------------------------------------------------*/
  798. void unique_name (fname)
  799. char *fname;
  800. {
  801.    static byte suffix[] = ".001";
  802.    register char *p;
  803.    register int n;
  804.  
  805.    if (dexists (fname))
  806.       {                                          /* If file already exists...       */
  807.       p = fname;
  808.       while (*p && *p != '.')
  809.          p++;                                     /* ...find the extension, if
  810.                                                   * any  */
  811.       for (n = 0; n < 4; n++)                     /* ...fill it out if
  812.                                                   * neccessary     */
  813.          if (!*p)
  814.             {
  815.             *p = suffix[n];
  816.             *(++p) = '\0';
  817.             }
  818.          else p++;
  819.  
  820.       while (dexists (fname))                     /* ...If 'file.ext' exists
  821.                                                   * suffix++ */
  822.          {
  823.          p = fname + strlen (fname) - 1;
  824.          for (n = 3; n--;)
  825.             {
  826.             if (!isdigit (*p))
  827.                *p = '0';
  828.             if (++(*p) <= '9')
  829.                break;
  830.             else *p-- = '0';
  831.             }                                     /* for */
  832.          }                                         /* while */
  833.       }                                          /* if exist */
  834. }                                                 /* unique_name */
  835.  
  836. int got_ESC ()
  837. {
  838.    if (((KEYPRESS ()) && (READKB () == 27)))     /* ESC pressed?        */
  839.       {
  840.       while (KEYPRESS ())
  841.          READKB ();
  842.       return (1);
  843.       }
  844.    return (0);
  845. }
  846.